package com.ecarx.vhaltests.hy11.testcases.drivemode;



import static vendor.ecarx.xma.automotive.vehicle.V2_0.ECarXVehicleProperty.SETTING_FUNC_PARK_COMFORT_MODE_TIMER;

import android.car.VehicleAreaType;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import vendor.ecarx.xma.automotive.vehicle.V2_0.CarMode;
import vendor.ecarx.xma.automotive.vehicle.V2_0.UsgModSts1;

//SW_FC_055_025 驻车舒适模式
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SettingFuncParkComfortModeTimerTest extends VhalUnitTestBase {

    private static final String TAG = "SETTING_FUNC_PARK_COMFORT_MODE_TIMER";
    private static final float PARK_COMFORT_STATUS_OFF = 0;
    private static final float PARK_COMFORT_STATUS_ON = 127.5F;


    private static IpcpClient ipcpClient = new IpcpClient();

    private static final int AREA_ID = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;

    private static float halValue;
    private static int halStatus;
    final static Object lock = new Object();

    @BeforeClass
    public static void testInit() {
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, SETTING_FUNC_PARK_COMFORT_MODE_TIMER, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig();
    }

    @Test
    public void testSettingFuncParkComfortModeTimerAvailable() {
        setSettingFuncParkComfortModeTimerAvailable();
        lockWait();
        Assert.assertEquals(halStatus, 0);
        testSettingFuncParkComfortModeTimerAvai();
    }

    @Test
    public void testSettingFuncParkComfortModeTimerNotAvailable() {
        setSettingFuncParkComfortModeTimerNotAvailable();
        lockWait();
        Assert.assertEquals(halStatus, 1);
        testSettingFuncParkComfortModeTimerNotAvai();
    }

    @Test
    public void testSettingFuncParkComfortModeTimerOff() {
        setSettingFuncParkComfortModeTimerAvailable();
        delay();
        setSettingFuncParkComfortModeTimerValue(PARK_COMFORT_STATUS_OFF);
        lockWait();
        Assert.assertEquals(halValue, PARK_COMFORT_STATUS_OFF, 0);
        testSettingFuncParkComfortModeTimerValue(PARK_COMFORT_STATUS_OFF);
    }

    @Test
    public void testSettingFuncParkComfortModeTimerOn() {
        setSettingFuncParkComfortModeTimerAvailable();
        delay();
        setSettingFuncParkComfortModeTimerValue(PARK_COMFORT_STATUS_ON);
        lockWait();
        Assert.assertEquals(halValue, PARK_COMFORT_STATUS_ON, 0);
        testSettingFuncParkComfortModeTimerValue(PARK_COMFORT_STATUS_ON);
    }

    @Test
    public void testSettingFuncParkComfortModeTimerMiddle() {
        setSettingFuncParkComfortModeTimerAvailable();
        delay();
        setSettingFuncParkComfortModeTimerValue(5.5f);
        lockWait();
        Assert.assertEquals(halValue, 5.5f, 0);
        testSettingFuncParkComfortModeTimerValue(5.5f);
    }

    private void testSettingFuncParkComfortModeTimerValue(float value){
        float halValue = mCarPropertyMgr.getFloatProperty(SETTING_FUNC_PARK_COMFORT_MODE_TIMER, AREA_ID);
        Assert.assertEquals(halValue, value, 0);
    }

    private void setSettingFuncParkComfortModeTimerValue(float value){
        mCarPropertyMgr.setFloatProperty(SETTING_FUNC_PARK_COMFORT_MODE_TIMER, AREA_ID, value);
    }

    private void setSettingFuncParkComfortModeTimerAvailable(){
        setDispHvBattLvlOfChrgAndChrgnOrDisChrgnStsFb(900, 2);
        setCarmodUsgMod(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_CONVENIENCE);
    }

    private void setSettingFuncParkComfortModeTimerNotAvailable(){
        setDispHvBattLvlOfChrgAndChrgnOrDisChrgnStsFb(10, 1);
        setCarmodUsgMod(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_CONVENIENCE);
    }

    private static void setConfig() {
        int ccSvcId = 135;
        int[] ccOperIds = {200};

        int cemSvcId = 37;
        int[] cemOperIds = {999};

        int vddmSvcId = 48;
        int[] vddmOperIds = {999};

        ipcpClient.setConfig(ccSvcId, ccOperIds);
        ipcpClient.setConfig(cemSvcId, cemOperIds);
        ipcpClient.setConfig(vddmSvcId, vddmOperIds);

        int[] configs = {13};
        int[] values = {4};
        boolean ccRet = ipcpClient.setCarconfigSignal(ccSvcId, ccOperIds[0], configs, values);
        Assert.assertTrue(ccRet);

    }

    private void setCarmodUsgMod(int carMod, int usgMod)
    {
        int cemSvcId = 37;
        int[] cemOperIds = {999};

        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts"};
        int[] cemValues = {carMod, usgMod};
        boolean cemRet = ipcpClient.setCEMSignal(cemSvcId, cemOperIds[0], cems, cemValues);
        Assert.assertTrue(cemRet);
    }

    private void setDispHvBattLvlOfChrgAndChrgnOrDisChrgnStsFb(int value, int value2){
        int vddmSvcId = 48;
        int[] vddmOperIds = {999};

        String[] vddms = {"dispHvBattLvlOfChrg", "chrgnOrDisChrgnStsFb"};
        int[] vddmValues = {value, value2};
        boolean vddmsRet = ipcpClient.setVDDMSignal(vddmSvcId, vddmOperIds[0], vddms, vddmValues);
        Assert.assertTrue(vddmsRet);
    }

    private void testSettingFuncParkComfortModeTimerAvai(){
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(SETTING_FUNC_PARK_COMFORT_MODE_TIMER, AREA_ID);
        Assert.assertTrue(isAvail);
    }

    private void testSettingFuncParkComfortModeTimerNotAvai(){
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(SETTING_FUNC_PARK_COMFORT_MODE_TIMER, AREA_ID);
        Assert.assertFalse(isAvail);
    }

    private static final CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                Log.d(TAG, carPropertyValue.toString());
                halValue = (float)carPropertyValue.getValue();
                halStatus = carPropertyValue.getStatus();
                synchronized (lock) {
                    lock.notify();
                }
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {
        }
    };

    public void lockWait() {
        try {
            synchronized (lock) {
                lock.wait(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}